﻿using AutoMapper;
using CommonEngine;
using System;
using System.Collections.Generic;
using System.Reflection;

namespace CommonDevelop
{
    /// <summary>
    /// AutoMapper扩展帮助类
    /// </summary>
    public static class AutoMapperHelper
    {
        /// <summary>
        ///  类型映射
        /// </summary>
        public static TDestination MapTo<TDestination>(this object source)
        {
            if (source == null)
                return default(TDestination);

            var config = new MapperConfiguration(cfg => cfg.CreateMap(source.GetType(), typeof(TDestination)));
            var mapper = config.CreateMapper();
            var des = mapper.Map<TDestination>(source);
            return des;
        }

        /// <summary>
        /// 集合列表类型映射
        /// </summary>
        public static List<TDestination> MapToList<TSource, TDestination>(this IEnumerable<TSource> source)
        {
            if (source.IsNullOrEmpty())
                return new List<TDestination>();

            var config = new MapperConfiguration(cfg => cfg.CreateMap(typeof(TSource), typeof(TDestination)));
            var mapper = config.CreateMapper();
            return mapper.Map<List<TDestination>>(source);
        }

        /// <summary>
        /// Dto对象合并
        /// </summary>
        public static T MergeDto<T>(this T inModel, T outModel)
            where T : class
        {
            if (inModel == null || outModel == null)
                return default(T);

            Type type = typeof(T);
            var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            foreach (var property in properties)
            {
                var value = property.GetValue(inModel);
                var valueOut = property.GetValue(outModel);
                if (value.IsEmpty() && !valueOut.IsEmpty())
                    property.SetValue(inModel, valueOut, null);
            }
            return inModel;
        }

        /// <summary>
        /// 实体合并
        /// </summary>
        public static T MergeEn<T>(this T OldModel, T NewModel)
            where T : class
        {
            if (OldModel == null || NewModel == null)
                return default(T);

            Type type = typeof(T);
            var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            foreach (var property in properties)
            {
                var value = property.GetValue(NewModel);
                if (value.IsEmpty())
                    continue;
                else
                    property.SetValue(OldModel, value, null);
            }
            return OldModel;
        }

    }
}
